home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / os / sprite.X11R3 / buf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-09-09  |  9.3 KB  |  402 lines

  1. /*-
  2.  * buf.c --
  3.  *    Functions for automatically-expanded buffers.
  4.  *
  5.  * Copyright (c) 1987 by the Regents of the University of California
  6.  *
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  *
  15.  *
  16.  */
  17. #ifndef lint
  18. static char rcsid[] =
  19. "$Header: buf.c,v 1.2 88/09/08 18:16:18 ouster Exp $ SPRITE (Berkeley)";
  20. #endif lint
  21.  
  22. #include <bstring.h>
  23. #include <stdlib.h>
  24. #include    "buf.h"
  25.  
  26. typedef struct {
  27.     int        size;     /* Current size of the buffer */
  28.     Byte    *buffer;    /* The buffer itself */
  29.     Byte    *inPtr;    /* Place to write to */
  30.     Byte    *outPtr;    /* Place to read from */
  31. } Buf, *BufPtr;
  32.  
  33. #ifndef max
  34. #define max(a,b)  ((a) > (b) ? (a) : (b))
  35. #endif
  36.  
  37. /*
  38.  * BufExpand --
  39.  *     Expand the given buffer to hold the given number of additional
  40.  *    bytes.
  41.  */
  42. #define BufExpand(bp,nb) \
  43.      if (((bp)->size - ((bp)->inPtr - (bp)->buffer)) < (nb)) {\
  44.         int newSize = (bp)->size + max((nb),BUF_ADD_INC); \
  45.         Byte  *newBuf = (Byte *) malloc ((unsigned) newSize); \
  46.         \
  47.         bcopy ((bp)->outPtr, newBuf, (bp)->inPtr - (bp)->outPtr); \
  48.         (bp)->inPtr = newBuf + ((bp)->inPtr - (bp)->outPtr); \
  49.         (bp)->outPtr = newBuf;\
  50.         free ((char *) (bp)->buffer);\
  51.         (bp)->buffer = newBuf;\
  52.         (bp)->size = newSize;\
  53.     }
  54.  
  55. #define BUF_DEF_SIZE    256     /* Default buffer size */
  56. #define BUF_ADD_INC    256     /* Expansion increment when Adding */
  57. #define BUF_UNGET_INC    16      /* Expansion increment when Ungetting */
  58.  
  59. /*-
  60.  *-----------------------------------------------------------------------
  61.  * Buf_AddByte --
  62.  *    Add a single byte to the buffer.
  63.  *
  64.  * Results:
  65.  *    None.
  66.  *
  67.  * Side Effects:
  68.  *    The buffer may be expanded.
  69.  *
  70.  *-----------------------------------------------------------------------
  71.  */
  72. void
  73. Buf_AddByte (buf, byte)
  74.     Buffer  buf;
  75.     Byte    byte;
  76. {
  77.     register BufPtr  bp = (BufPtr) buf;
  78.  
  79.     BufExpand (bp, 1);
  80.  
  81.     *bp->inPtr = byte;
  82.     bp->inPtr += 1;
  83. }
  84.  
  85. /*-
  86.  *-----------------------------------------------------------------------
  87.  * Buf_AddBytes --
  88.  *    Add a number of bytes to the buffer.
  89.  *
  90.  * Results:
  91.  *    None.
  92.  *
  93.  * Side Effects:
  94.  *    Guess what?
  95.  *
  96.  *-----------------------------------------------------------------------
  97.  */
  98. void
  99. Buf_AddBytes (buf, numBytes, bytesPtr)
  100.     Buffer  buf;
  101.     int        numBytes;
  102.     Byte    *bytesPtr;
  103. {
  104.     register BufPtr  bp = (BufPtr) buf;
  105.  
  106.     BufExpand (bp, numBytes);
  107.  
  108.     bcopy (bytesPtr, bp->inPtr, numBytes);
  109.     bp->inPtr += numBytes;
  110. }
  111.  
  112. /*-
  113.  *-----------------------------------------------------------------------
  114.  * Buf_UngetByte --
  115.  *    Place the byte back at the beginning of the buffer.
  116.  *
  117.  * Results:
  118.  *    SUCCESS if the byte was added ok. FAILURE if not.
  119.  *
  120.  * Side Effects:
  121.  *    The byte is stuffed in the buffer and outPtr is decremented.
  122.  *
  123.  *-----------------------------------------------------------------------
  124.  */
  125. void
  126. Buf_UngetByte (buf, byte)
  127.     Buffer  buf;
  128.     Byte    byte;
  129. {
  130.     register BufPtr    bp = (BufPtr) buf;
  131.  
  132.     if (bp->outPtr != bp->buffer) {
  133.     bp->outPtr -= 1;
  134.     *bp->outPtr = byte;
  135.     } else if (bp->outPtr == bp->inPtr) {
  136.     *bp->inPtr = byte;
  137.     bp->inPtr += 1;
  138.     } else {
  139.     /*
  140.      * Yech. have to expand the buffer to stuff this thing in.
  141.      * We use a different expansion constant because people don't
  142.      * usually push back many bytes when they're doing it a byte at
  143.      * a time...
  144.      */
  145.     int       numBytes = bp->inPtr - bp->outPtr;
  146.     Byte      *newBuf;
  147.  
  148.     newBuf = (Byte *) malloc ((unsigned) (bp->size + BUF_UNGET_INC));
  149.     bcopy ((char *) bp->outPtr, (char *) (newBuf+BUF_UNGET_INC), numBytes);
  150.     bp->outPtr = newBuf + BUF_UNGET_INC;
  151.     bp->inPtr = bp->outPtr + numBytes;
  152.     free ((char *)bp->buffer);
  153.     bp->buffer = newBuf;
  154.     bp->size += BUF_UNGET_INC;
  155.     bp->outPtr -= 1;
  156.     *bp->outPtr = byte;
  157.     }
  158. }
  159.  
  160. /*-
  161.  *-----------------------------------------------------------------------
  162.  * Buf_UngetBytes --
  163.  *    Push back a series of bytes at the beginning of the buffer.
  164.  *
  165.  * Results:
  166.  *    None.
  167.  *
  168.  * Side Effects:
  169.  *    outPtr is decremented and the bytes copied into the buffer.
  170.  *
  171.  *-----------------------------------------------------------------------
  172.  */
  173. void
  174. Buf_UngetBytes (buf, numBytes, bytesPtr)
  175.     Buffer  buf;
  176.     int        numBytes;
  177.     Byte    *bytesPtr;
  178. {
  179.     register BufPtr    bp = (BufPtr) buf;
  180.  
  181.     if (bp->outPtr - bp->buffer >= numBytes) {
  182.     bp->outPtr -= numBytes;
  183.     bcopy ((char *) bytesPtr, (char *) bp->outPtr, numBytes);
  184.     } else if (bp->outPtr == bp->inPtr) {
  185.     Buf_AddBytes (buf, numBytes, bytesPtr);
  186.     } else {
  187.     int       curNumBytes = bp->inPtr - bp->outPtr;
  188.     Byte      *newBuf;
  189.     int       newBytes = max(numBytes,BUF_UNGET_INC);
  190.  
  191.     newBuf = (Byte *) malloc ((unsigned) (bp->size + newBytes));
  192.     bcopy((char *) bp->outPtr, (char *) (newBuf+newBytes), curNumBytes);
  193.     bp->outPtr = newBuf + newBytes;
  194.     bp->inPtr = bp->outPtr + curNumBytes;
  195.     free ((char *)bp->buffer);
  196.     bp->buffer = newBuf;
  197.     bp->size += newBytes;
  198.     bp->outPtr -= numBytes;
  199.     bcopy((char *) bytesPtr, (char *) bp->outPtr, numBytes);
  200.     }
  201. }
  202.  
  203. /*-
  204.  *-----------------------------------------------------------------------
  205.  * Buf_GetByte --
  206.  *    Return the next byte from the buffer. Actually returns an integer.
  207.  *
  208.  * Results:
  209.  *    Returns BUF_ERROR if there's no byte in the buffer, or the byte
  210.  *    itself if there is one.
  211.  *
  212.  * Side Effects:
  213.  *    outPtr is incremented and both outPtr and inPtr will be reset if
  214.  *    the buffer is emptied.
  215.  *
  216.  *-----------------------------------------------------------------------
  217.  */
  218. int
  219. Buf_GetByte (buf)
  220.     Buffer  buf;
  221. {
  222.     BufPtr  bp = (BufPtr) buf;
  223.     int        res;
  224.  
  225.     if (bp->inPtr == bp->outPtr) {
  226.     return (BUF_ERROR);
  227.     } else {
  228.     res = (int) *bp->outPtr;
  229.     bp->outPtr += 1;
  230.     if (bp->outPtr == bp->inPtr) {
  231.         bp->outPtr = bp->inPtr = bp->buffer;
  232.     }
  233.     return (res);
  234.     }
  235. }
  236.  
  237. /*-
  238.  *-----------------------------------------------------------------------
  239.  * Buf_GetBytes --
  240.  *    Extract a number of bytes from the buffer.
  241.  *
  242.  * Results:
  243.  *    The number of bytes gotten.
  244.  *
  245.  * Side Effects:
  246.  *    The passed array is overwritten.
  247.  *
  248.  *-----------------------------------------------------------------------
  249.  */
  250. int
  251. Buf_GetBytes (buf, numBytes, bytesPtr)
  252.     Buffer  buf;
  253.     int        numBytes;
  254.     Byte    *bytesPtr;
  255. {
  256.     BufPtr  bp = (BufPtr) buf;
  257.     
  258.     if (bp->inPtr - bp->outPtr < numBytes) {
  259.     numBytes = bp->inPtr - bp->outPtr;
  260.     }
  261.     bcopy ((char *) bp->outPtr, (char *) bytesPtr, numBytes);
  262.     bp->outPtr += numBytes;
  263.  
  264.     if (bp->outPtr == bp->inPtr) {
  265.     bp->outPtr = bp->inPtr = bp->buffer;
  266.     }
  267.     return (numBytes);
  268. }
  269.  
  270. /*-
  271.  *-----------------------------------------------------------------------
  272.  * Buf_GetAll --
  273.  *    Get all the available data at once.
  274.  *
  275.  * Results:
  276.  *    A pointer to the data and the number of bytes available.
  277.  *
  278.  * Side Effects:
  279.  *    None.
  280.  *
  281.  *-----------------------------------------------------------------------
  282.  */
  283. Byte *
  284. Buf_GetAll (buf, numBytesPtr)
  285.     Buffer  buf;
  286.     int        *numBytesPtr;
  287. {
  288.     BufPtr  bp = (BufPtr)buf;
  289.  
  290.     if (numBytesPtr != (int *)NULL) {
  291.     *numBytesPtr = bp->inPtr - bp->outPtr;
  292.     }
  293.     
  294.     return (bp->outPtr);
  295. }
  296.  
  297. /*-
  298.  *-----------------------------------------------------------------------
  299.  * Buf_Discard --
  300.  *    Throw away bytes in a buffer.
  301.  *
  302.  * Results:
  303.  *    None.
  304.  *
  305.  * Side Effects:
  306.  *    The bytes are discarded. 
  307.  *
  308.  *-----------------------------------------------------------------------
  309.  */
  310. void
  311. Buf_Discard (buf, numBytes)
  312.     Buffer  buf;
  313.     int        numBytes;
  314. {
  315.     register BufPtr    bp = (BufPtr) buf;
  316.  
  317.     if (bp->inPtr - bp->outPtr <= numBytes) {
  318.     bp->inPtr = bp->outPtr = bp->buffer;
  319.     } else {
  320.     bp->outPtr += numBytes;
  321.     }
  322. }
  323.  
  324. /*-
  325.  *-----------------------------------------------------------------------
  326.  * Buf_Size --
  327.  *    Returns the number of bytes in the given buffer.
  328.  *
  329.  * Results:
  330.  *    The number of bytes.
  331.  *
  332.  * Side Effects:
  333.  *    None.
  334.  *
  335.  *-----------------------------------------------------------------------
  336.  */
  337. int
  338. Buf_Size (buf)
  339.     Buffer  buf;
  340. {
  341.     return (((BufPtr)buf)->inPtr - ((BufPtr)buf)->outPtr);
  342. }
  343.  
  344. /*-
  345.  *-----------------------------------------------------------------------
  346.  * Buf_Init --
  347.  *    Initialize a buffer. If no initial size is given, a reasonable
  348.  *    default is used.
  349.  *
  350.  * Results:
  351.  *    A buffer to be given to other functions in this library.
  352.  *
  353.  * Side Effects:
  354.  *    The buffer is created, the space allocated and pointers
  355.  *    initialized.
  356.  *
  357.  *-----------------------------------------------------------------------
  358.  */
  359. Buffer
  360. Buf_Init (size)
  361.     int        size;     /* Initial size for the buffer */
  362. {
  363.     BufPtr  bp;          /* New Buffer */
  364.  
  365.     bp = (Buf *) malloc(sizeof(Buf));
  366.  
  367.     if (size <= 0) {
  368.     size = BUF_DEF_SIZE;
  369.     }
  370.     bp->size = size;
  371.     bp->buffer = (Byte *) malloc ((unsigned) size);
  372.     bp->inPtr = bp->outPtr = bp->buffer;
  373.  
  374.     return ((Buffer) bp);
  375. }
  376.  
  377. /*-
  378.  *-----------------------------------------------------------------------
  379.  * Buf_Destroy --
  380.  *    Nuke a buffer and all its resources.
  381.  *
  382.  * Results:
  383.  *    None.
  384.  *
  385.  * Side Effects:
  386.  *    The buffer is freed.
  387.  *
  388.  *-----------------------------------------------------------------------
  389.  */
  390. void
  391. Buf_Destroy (buf, freeData)
  392.     Buffer  buf;      /* Buffer to destroy */
  393.     Boolean freeData;    /* TRUE if the data should be destroyed as well */
  394. {
  395.     BufPtr  bp = (BufPtr) buf;
  396.     
  397.     if (freeData) {
  398.     free ((char *)bp->buffer);
  399.     }
  400.     free ((char *)bp);
  401. }
  402.